package com.example.segflow.service.task;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.segflow.model.*;
import com.example.segflow.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * segflow MapperService class
 *
 * @author xisheng
 * @date 2022/12/29
 */
@Service
@Slf4j
public class MapperService {

    @Autowired
    GantryFlowCarService gantryFlowCarService;
    @Autowired
    GantryBasicXfzService gantryBasicXfzService;
    @Autowired
    SegTrafficFlowTmpRawService segTrafficFlowTmpRawService;
    @Autowired
    GantryFlowTruckService gantryFlowTruckService;
    @Autowired
    SegTrafficFlowDetailDailyService segTrafficFlowDetailDailyService;


    public void countSegVehFlowDaily(){
        /* 设置起止时间 */
        Date dateStart = DateUtil.parse("2022-10-01");
        Date dateEnd = DateUtil.parseDate("2022-11-01");

        Date dateTmp = dateStart;
        while (dateTmp.before(dateEnd)){
            countSegTraffic(dateTmp);
            dateTmp = DateUtil.offsetDay(dateTmp,1);
        }
    }

    public void countSegTraffic (Date splitDate) {

        List<SegTrafficFlowTmpRaw> rawList = new ArrayList<>();
        QueryWrapper<GantryFlowCar> qwFlow = new QueryWrapper<>();

        qwFlow.lambda().eq(GantryFlowCar::getTransTime,splitDate);
        List<GantryFlowCar> gantryFlowCarList = gantryFlowCarService.list(qwFlow);
        for(GantryFlowCar flowCar : gantryFlowCarList) {
            SegTrafficFlowTmpRaw raw = segTrafficFlowDaily(flowCar);
            rawList.add(raw);
        }

        /*将客车和货车的初步统计汇总到临时表 egTrafficFlowTmpRaw*/
        segTrafficFlowTmpRawService.saveBatch(rawList);

        /*计算门架路段车流量*/
        countSegTrafficDaily(splitDate);

        //今日统计结束，清空临时表
        segTrafficFlowTmpRawService.delAll();
        log.info("{}统计结束，清空临时表",DateUtil.format(splitDate,"yyyyMMdd"));
    }

    /**
     * 按日！！
     * @param flowCar
     */
    private SegTrafficFlowTmpRaw segTrafficFlowDaily (GantryFlowCar flowCar) {

        //门架编号关联到路段 - 路段收费里程
        String gantryId = flowCar.getGantryId();
        QueryWrapper<GantryBasicXfz> qwGantry = new QueryWrapper<>();
        qwGantry.lambda().eq(GantryBasicXfz::getGantryId,gantryId);
        GantryBasicXfz gantryBasicXfz = gantryBasicXfzService.getOne(qwGantry);
        Long vehFlow = flowCar.getVehicleFlow();
        Long tollLen = gantryBasicXfz.getTollIntervalLength();
        Long segLen = gantryBasicXfz.getSegIntervalLength();
        String segName = gantryBasicXfz.getSegName();
        String segCode = gantryBasicXfz.getSegCode();
        String tollInterId = gantryBasicXfz.getTollIntervalId();

        //找到对应的货车记录
        QueryWrapper<GantryFlowTruck> qwTruck = new QueryWrapper<>();
        qwTruck.lambda().eq(GantryFlowTruck::getGantryId,gantryId)
                .eq(GantryFlowTruck::getTransTime,flowCar.getTransTime());
        GantryFlowTruck flowTruck = gantryFlowTruckService.getOne(qwTruck);
        Long truckFlow = 0L;
        if(flowTruck != null){
            truckFlow = flowTruck.getVehicleFlow();
        }

        //保存到临时记录表
        SegTrafficFlowTmpRaw tmpRaw = new SegTrafficFlowTmpRaw();
        tmpRaw.setGantryId(gantryId);
        tmpRaw.setSegVehicleFlow(vehFlow);
        tmpRaw.setSegTruckFlow(truckFlow);
        tmpRaw.setTollIntervalId(tollInterId);
        tmpRaw.setSegCode(segCode);
        tmpRaw.setSegName(segName);
        tmpRaw.setOrgaCode(gantryBasicXfz.getOrgaCode());
        tmpRaw.setOrgaName(gantryBasicXfz.getSegName());
        tmpRaw.setSegIntervalLength(segLen);
        tmpRaw.setTollIntervalLength(tollLen);
        return tmpRaw;

    }

    public void countSegTrafficDaily (Date splitDate) {
        QueryWrapper<GantryBasicXfz> qwGantry = new QueryWrapper<>();
        qwGantry.select("DISTINCT(seg_name) segName,seg_code segCode,orga_code orgaCode,orga_name orgaName");

        List<GantryBasicXfz> gantryBasicXfzList = gantryBasicXfzService.list(qwGantry);

        for(GantryBasicXfz gantryBasicXfz : gantryBasicXfzList){
            String segName = gantryBasicXfz.getSegName();
            String segCode;
            QueryWrapper<SegTrafficFlowTmpRaw> qwRaw = new QueryWrapper<>();
            qwRaw.lambda().eq(SegTrafficFlowTmpRaw::getSegName,segName);

            //同一路段的
            List<SegTrafficFlowTmpRaw> rawList = segTrafficFlowTmpRawService.list(qwRaw);

            if(rawList == null || rawList.size() == 0){
                log.info("警告!空路段名{}",segName);
                continue;
            }

            SegTrafficFlowDetailDaily detailDaily = countSeg(rawList);

            if(gantryBasicXfz.getSegCode() == null){
                segCode = "089";
            }else {
                segCode = gantryBasicXfz.getSegCode();
            }
            detailDaily.setId(gantryBasicXfz.getOrgaCode()+segCode+DateUtil.format(splitDate,"yyyyMMdd"));
            detailDaily.setCheckDate(splitDate);
            detailDaily.setOrgId(gantryBasicXfz.getOrgaCode());
            detailDaily.setOrgName(gantryBasicXfz.getOrgaName());
            detailDaily.setSegCode(gantryBasicXfz.getSegCode());
            detailDaily.setSegName(segName);
            segTrafficFlowDetailDailyService.save(detailDaily);

        }

    }


    /**
     * 根据SegTrafficFlowTmpRaw 计算同一路段的车流量 按日
     * @param rawList
     */
    private SegTrafficFlowDetailDaily countSeg (List<SegTrafficFlowTmpRaw> rawList) {

        SegTrafficFlowDetailDaily detailDaily = new SegTrafficFlowDetailDaily();

        /* 路段起止里程 */
        Long segIntervalLength = rawList.get(0).getSegIntervalLength();
        /* 路段名 */
        String segName = rawList.get(0).getSegName();

        Long upper = 0L;
        Long upperTruck = 0L;

        for(SegTrafficFlowTmpRaw tmpRaw : rawList){

            /*路段客车流量*/
            Long gantryFlow = tmpRaw.getSegVehicleFlow();
            /*收费单元起止里程*/
            Long tollIntervalLength= tmpRaw.getTollIntervalLength();

            /*客车分子 = 路段客车流量 × 收费单元起止里程*/
            upper += gantryFlow * tollIntervalLength;

            /*路段货车流量*/
            Long truckFlow = tmpRaw.getSegTruckFlow();
            /*货车分子 = 路段货车流量 × 收费单元起止里程*/
            upperTruck += truckFlow * tollIntervalLength;
        }

        /*路段门架客车流量 = 客车分子/路段起止里程*/
        Long avgFlow = upper / segIntervalLength;
        /*路段门架货车流量 = 货车分子/路段起止里程 */
        Long avgTruckFlow = upperTruck / segIntervalLength;
        log.info("打印--路段:{},车流:{}",segName,avgFlow);

        detailDaily.setTruckFlow(avgTruckFlow);
        detailDaily.setCarFlow(avgFlow);
        detailDaily.setTotalFlow(avgFlow+avgTruckFlow);
        return detailDaily;
    }

}
